/*******************************
            Set-up
*******************************/

var fs = require("fs"),
  path = require("path"),
  defaults = require("../defaults"),
  release = require("./release"),
  requireDotFile = require("require-dot-file");

/*******************************
          When to Ask
*******************************/

/* Preconditions for install questions */

var when = {
  // path
  changeRoot: function(questions) {
    return questions.useRoot !== undefined && questions.useRoot !== true;
  },

  // permissions
  changePermissions: function(questions) {
    return questions.changePermissions && questions.changePermissions === true;
  },

  // install
  hasConfig: function() {
    return requireDotFile("semantic.json", process.cwd());
  },

  allowOverwrite: function(questions) {
    return questions.overwrite === undefined || questions.overwrite == "yes";
  },
  notAuto: function(questions) {
    return (
      questions.install !== "auto" &&
      (questions.overwrite === undefined || questions.overwrite == "yes")
    );
  },
  custom: function(questions) {
    return (
      questions.install === "custom" &&
      (questions.overwrite === undefined || questions.overwrite == "yes")
    );
  },
  express: function(questions) {
    return (
      questions.install === "express" &&
      (questions.overwrite === undefined || questions.overwrite == "yes")
    );
  },

  // customize
  customize: function(questions) {
    return questions.customize === true;
  },
  primaryColor: function(questions) {
    return questions.primaryColor;
  },
  secondaryColor: function(questions) {
    return questions.secondaryColor;
  }
};

/*******************************
        Response Filters
*******************************/

/* Filters to user input from install questions */

var filter = {
  removeTrailingSlash: function(path) {
    return path.replace(/(\/$|\\$)+/gm, "");
  }
};

/*******************************
          Configuration
*******************************/

module.exports = {
  // check whether install is setup
  isSetup: function() {
    return when.hasConfig();
  },

  // detect whether there is a semantic.json configuration and that the auto-install option is set to true
  shouldAutoInstall: function() {
    var config = when.hasConfig();
    return config["autoInstall"];
  },

  // checks if files are in a PM directory
  getPackageManager: function(directory) {
    var // returns last matching result (avoid sub-module detection)
    walk = function(directory) {
      var pathArray = directory.split(path.sep),
        folder = pathArray[pathArray.length - 1],
        nextDirectory = path.join(directory, path.sep, "..");
      if (folder == "bower_components") {
        return {
          name: "Bower",
          root: nextDirectory
        };
      } else if (folder == "node_modules") {
        return {
          name: "NPM",
          root: nextDirectory
        };
      } else if (folder == "composer") {
        return {
          name: "Composer",
          root: nextDirectory
        };
      }
      if (path.resolve(directory) == path.resolve(nextDirectory)) {
        return false;
      }
      // recurse downward
      return walk(nextDirectory);
    };
    // start walk from current directory if none specified
    directory = directory || __dirname + path.sep;
    return walk(directory);
  },

  // checks if files is PMed submodule
  isSubModule: function(directory) {
    var moduleFolders = 0,
      walk = function(directory) {
        var pathArray = directory.split(path.sep),
          folder = pathArray[pathArray.length - 2],
          nextDirectory = path.join(directory, path.sep, "..");
        if (folder == "bower_components") {
          moduleFolders++;
        } else if (folder == "node_modules") {
          moduleFolders++;
        } else if (folder == "composer") {
          moduleFolders++;
        }
        if (path.resolve(directory) == path.resolve(nextDirectory)) {
          return moduleFolders > 1;
        }
        // recurse downward
        return walk(nextDirectory);
      };
    // start walk from current directory if none specified
    directory = directory || __dirname + path.sep;
    return walk(directory);
  },

  createJSON: function(answers) {
    var json = {
      paths: {
        source: {},
        output: {}
      }
    };

    // add components
    if (answers.components) {
      json.components = answers.components;
    }

    // add rtl choice
    if (answers.rtl) {
      json.rtl = answers.rtl;
    }

    // add permissions
    if (answers.permission) {
      json.permission = answers.permission;
    }

    // add path to semantic
    if (answers.semanticRoot) {
      json.base = path.normalize(answers.semanticRoot);
    }

    // record version number to avoid re-installing on same version
    json.version = release.version;

    // add dist folder paths
    if (answers.dist) {
      answers.dist = path.normalize(answers.dist);

      json.paths.output = {
        packaged: path.normalize(answers.dist + "/"),
        uncompressed: path.normalize(answers.dist + "/components/"),
        compressed: path.normalize(answers.dist + "/components/"),
        themes: path.normalize(answers.dist + "/themes/")
      };
    }

    // add site path
    if (answers.site) {
      json.paths.source.site = path.normalize(answers.site + "/");
    }
    if (answers.packaged) {
      json.paths.output.packaged = path.normalize(answers.packaged + "/");
    }
    if (answers.compressed) {
      json.paths.output.compressed = path.normalize(answers.compressed + "/");
    }
    if (answers.uncompressed) {
      json.paths.output.uncompressed = path.normalize(
        answers.uncompressed + "/"
      );
    }
    return json;
  },

  // files cleaned up after install
  setupFiles: [
    "./src/theme.config.example",
    "./semantic.json.example",
    "./src/_site"
  ],

  regExp: {
    // used to match siteFolder variable in theme.less
    siteVariable: /@siteFolder .*\'(.*)/gm
  },

  // source paths (when installing)
  source: {
    config: "./semantic.json.example",
    definitions: "./src/definitions",
    gulpFile: "./gulpfile.js",
    lessImport: "./src/semantic.less",
    site: "./src/_site",
    tasks: "./tasks",
    themeConfig: "./src/theme.config.example",
    themeImport: "./src/theme.less",
    themes: "./src/themes",
    defaultTheme: "./src/themes/default",
    userGulpFile: "./tasks/config/npm/gulpfile.js"
  },

  // expected final filenames
  files: {
    config: "semantic.json",
    lessImport: "src/semantic.less",
    site: "src/site",
    themeConfig: "src/theme.config",
    themeImport: "src/theme.less"
  },

  // folder paths to files relative to root
  folders: {
    config: "./",
    definitions: "src/definitions/",
    lessImport: "src/",
    modules: "node_modules/",
    site: "src/site/",
    tasks: "tasks/",
    themeConfig: "src/",
    themeImport: "src/",
    themes: "src/themes/",

    defaultTheme: "default/" // only path that is relative to another directory and not root
  },

  // questions asked during install
  questions: {
    root: [
      {
        type: "list",
        name: "useRoot",
        message: "{packageMessage} Is this your project folder? {root}",
        choices: [
          {
            name: "Yes",
            value: true
          },
          {
            name: "No, let me specify",
            value: false
          }
        ]
      },
      {
        type: "input",
        name: "customRoot",
        message: "Please enter the absolute path to your project root",
        default: "/my/project/path",
        when: when.changeRoot
      },
      {
        type: "input",
        name: "semanticRoot",
        message: "Where should we put Semantic UI inside your project?",
        default: "semantic/"
      }
    ],

    setup: [
      {
        type: "list",
        name: "overwrite",
        message: "It looks like you have a semantic.json file already.",
        when: when.hasConfig,
        choices: [
          {
            name: "Yes, extend my current settings.",
            value: "yes"
          },
          {
            name: "Skip install",
            value: "no"
          }
        ]
      },
      {
        type: "list",
        name: "install",
        message: "Set-up Semantic UI",
        when: when.allowOverwrite,
        choices: [
          {
            name: "Automatic (Use default locations and all components)",
            value: "auto"
          },
          {
            name: "Express (Set components and output folder)",
            value: "express"
          },
          {
            name: "Custom (Customize all src/dist values)",
            value: "custom"
          }
        ]
      },
      {
        type: "checkbox",
        name: "components",
        message: "What components should we include in the package?",

        // duplicated manually from tasks/defaults.js with additional property
        choices: [
          { name: "reset", checked: true },
          { name: "site", checked: true },
          { name: "button", checked: true },
          { name: "container", checked: true },
          { name: "divider", checked: true },
          { name: "flag", checked: true },
          { name: "header", checked: true },
          { name: "icon", checked: true },
          { name: "image", checked: true },
          { name: "input", checked: true },
          { name: "label", checked: true },
          { name: "list", checked: true },
          { name: "loader", checked: true },
          { name: "rail", checked: true },
          { name: "reveal", checked: true },
          { name: "segment", checked: true },
          { name: "step", checked: true },
          { name: "breadcrumb", checked: true },
          { name: "form", checked: true },
          { name: "grid", checked: true },
          { name: "menu", checked: true },
          { name: "message", checked: true },
          { name: "table", checked: true },
          { name: "ad", checked: true },
          { name: "card", checked: true },
          { name: "comment", checked: true },
          { name: "feed", checked: true },
          { name: "item", checked: true },
          { name: "statistic", checked: true },
          { name: "accordion", checked: true },
          { name: "checkbox", checked: true },
          { name: "dimmer", checked: true },
          { name: "dropdown", checked: true },
          { name: "embed", checked: true },
          { name: "modal", checked: true },
          { name: "nag", checked: true },
          { name: "popup", checked: true },
          { name: "progress", checked: true },
          { name: "rating", checked: true },
          { name: "search", checked: true },
          { name: "shape", checked: true },
          { name: "sidebar", checked: true },
          { name: "sticky", checked: true },
          { name: "tab", checked: true },
          { name: "transition", checked: true },
          { name: "api", checked: true },
          { name: "form", checked: true },
          { name: "state", checked: true },
          { name: "visibility", checked: true }
        ],
        when: when.notAuto
      },
      {
        type: "list",
        name: "changePermissions",
        when: when.notAuto,
        message: "Should we set permissions on outputted files?",
        choices: [
          {
            name: "No",
            value: false
          },
          {
            name: "Yes",
            value: true
          }
        ]
      },
      {
        type: "input",
        name: "permission",
        message: "What octal file permission should outputted files receive?",
        default: defaults.permission,
        when: when.changePermissions
      },
      {
        type: "list",
        name: "rtl",
        message: "Do you use a RTL (Right-To-Left) language?",
        when: when.notAuto,
        choices: [
          {
            name: "No",
            value: false
          },
          {
            name: "Yes",
            value: true
          },
          {
            name: "Build Both",
            value: "both"
          }
        ]
      },
      {
        type: "input",
        name: "dist",
        message: "Where should we output Semantic UI?",
        default: defaults.paths.output.packaged,
        filter: filter.removeTrailingSlash,
        when: when.express
      },
      {
        type: "input",
        name: "site",
        message: "Where should we put your site folder?",
        default: defaults.paths.source.site,
        filter: filter.removeTrailingSlash,
        when: when.custom
      },
      {
        type: "input",
        name: "packaged",
        message: "Where should we output a packaged version?",
        default: defaults.paths.output.packaged,
        filter: filter.removeTrailingSlash,
        when: when.custom
      },
      {
        type: "input",
        name: "compressed",
        message: "Where should we output compressed components?",
        default: defaults.paths.output.compressed,
        filter: filter.removeTrailingSlash,
        when: when.custom
      },
      {
        type: "input",
        name: "uncompressed",
        message: "Where should we output uncompressed components?",
        default: defaults.paths.output.uncompressed,
        filter: filter.removeTrailingSlash,
        when: when.custom
      }
    ],

    cleanup: [
      {
        type: "list",
        name: "cleanup",
        message: "Should we remove set-up files?",
        choices: [
          {
            name: "Yes (re-install will require redownloading semantic).",
            value: "yes"
          },
          {
            name: "No Thanks",
            value: "no"
          }
        ]
      },
      {
        type: "list",
        name: "build",
        message: "Do you want to build Semantic now?",
        choices: [
          {
            name: "Yes",
            value: "yes"
          },
          {
            name: "No",
            value: "no"
          }
        ]
      }
    ],
    site: [
      {
        type: "list",
        name: "customize",
        message:
          "You have not yet customized your site, can we help you do that?",
        choices: [
          {
            name: "Yes, ask me a few questions",
            value: true
          },
          {
            name: "No I'll do it myself",
            value: false
          }
        ]
      },
      {
        type: "list",
        name: "headerFont",
        message: "Select your header font",
        choices: [
          {
            name: "Helvetica Neue, Arial, sans-serif",
            value: "Helvetica Neue, Arial, sans-serif;"
          },
          {
            name: "Lato (Google Fonts)",
            value: "Lato"
          },
          {
            name: "Open Sans (Google Fonts)",
            value: "Open Sans"
          },
          {
            name: "Source Sans Pro (Google Fonts)",
            value: "Source Sans Pro"
          },
          {
            name: "Droid (Google Fonts)",
            value: "Droid"
          },
          {
            name: "I'll choose on my own",
            value: false
          }
        ],
        when: when.customize
      },
      {
        type: "list",
        name: "pageFont",
        message: "Select your page font",
        choices: [
          {
            name: "Helvetica Neue, Arial, sans-serif",
            value: "Helvetica Neue, Arial, sans-serif;"
          },
          {
            name: "Lato (Import from Google Fonts)",
            value: "Lato"
          },
          {
            name: "Open Sans (Import from Google Fonts)",
            value: "Open Sans"
          },
          {
            name: "Source Sans Pro (Import from Google Fonts)",
            value: "Source Sans Pro"
          },
          {
            name: "Droid (Google Fonts)",
            value: "Droid"
          },
          {
            name: "I'll choose on my own",
            value: false
          }
        ],
        when: when.customize
      },
      {
        type: "list",
        name: "fontSize",
        message: "Select your base font size",
        default: "14px",
        choices: [
          {
            name: "12px"
          },
          {
            name: "13px"
          },
          {
            name: "14px (Recommended)",
            value: "14px"
          },
          {
            name: "15px"
          },
          {
            name: "16px"
          },
          {
            name: "I'll choose on my own",
            value: false
          }
        ],
        when: when.customize
      },
      {
        type: "list",
        name: "primaryColor",
        message: "Select the closest name for your primary brand color",
        default: "14px",
        choices: [
          {
            name: "Blue"
          },
          {
            name: "Green"
          },
          {
            name: "Orange"
          },
          {
            name: "Pink"
          },
          {
            name: "Purple"
          },
          {
            name: "Red"
          },
          {
            name: "Teal"
          },
          {
            name: "Yellow"
          },
          {
            name: "Black"
          },
          {
            name: "I'll choose on my own",
            value: false
          }
        ],
        when: when.customize
      },
      {
        type: "input",
        name: "PrimaryHex",
        message: "Enter a hexcode for your primary brand color",
        when: when.primaryColor
      },
      {
        type: "list",
        name: "secondaryColor",
        message: "Select the closest name for your secondary brand color",
        default: "14px",
        choices: [
          {
            name: "Blue"
          },
          {
            name: "Green"
          },
          {
            name: "Orange"
          },
          {
            name: "Pink"
          },
          {
            name: "Purple"
          },
          {
            name: "Red"
          },
          {
            name: "Teal"
          },
          {
            name: "Yellow"
          },
          {
            name: "Black"
          },
          {
            name: "I'll choose on my own",
            value: false
          }
        ],
        when: when.customize
      },
      {
        type: "input",
        name: "secondaryHex",
        message: "Enter a hexcode for your secondary brand color",
        when: when.secondaryColor
      }
    ]
  },

  settings: {
    /* Rename Files */
    rename: {
      json: { extname: ".json" }
    },

    /* Copy Install Folders */
    wrench: {
      // overwrite existing files update & install (default theme / definition)
      overwrite: {
        forceDelete: true,
        excludeHiddenUnix: true,
        preserveFiles: false
      },

      // only create files that don't exist (site theme update)
      merge: {
        forceDelete: false,
        excludeHiddenUnix: true,
        preserveFiles: true
      }
    }
  }
};
